#! /usr/bin/env python
#coding=utf-8


from get_month_quarter import *
from get_tasks_develop_report_detail import get_task_plan_delay
db = get_db_connection()

#meta = MetaData(db)
#db.metadata.reflect()
#--------------------每日备份测试功能点开始--------------------#
def run_test_function_backup():
    
    #从settings.ini获取任务类型编号
    settings = Ini('../apps/settings.ini')
    
    today = datetime.date.today()
    #assignment_type = dict(settings.PARA.ASSIGNMENT_TYPE)
    req_test = get_model('test')
    req_his = get_model('test_history')
    req_rate = get_model('test_finish_rate')
    #归档历史数据,存在问题，新增部分没有插入历史表
    req = select([req_test.c.id,
                  req_test.c.system,
                  req_test.c.function_name,
                  req_test.c.function_code,
                  req_test.c.function_type,
                  req_test.c.change_status,
                  req_test.c.using_status,
                  req_test.c.function_point,
                  req_test.c.business_degree,
                  req_test.c.trading_frequency,
                  req_test.c.across_system,
                  req_test.c.trading_origin,
                  req_test.c.trading_route,
                  req_test.c.daily_visit,
                  req_test.c.test_version,
#                  req_test.c.function_flag,
#                  req_test.c.test_flag,
                  req_test.c.version_date,
                  req_test.c.test_status,
                  req_test.c.function_endtime,
                  req_test.c.lock_flag,
                  req_test.c.modified_date,
                  req_test.c.modifield_user,
                  req_test.c.subsystem_abbr,
                  req_test.c.subsystem_name],
                and_(req_test.c.version_date >= today,req_test.c.id.in_(select([req_his.c.test_id]))))
#    print 'req',req
    req_rs = req.execute()
    data = {}
    for row in req_rs:
        row = list(row)
        
        #print 'firstrow',row
        
        data['test_id']           = row[0]
        data['system']            = row[1] 
        data['function_name']     = row[2] 
        data['function_code']     = row[3] 
        data['function_type']     = row[4] 
        data['change_status']     = row[5] 
        data['using_status']      = row[6] 
        data['function_point']    = row[7] 
        data['business_degree']   = row[8] 
        data['trading_frequency'] = row[9] 
        data['across_system']     = row[10]
        data['trading_origin']    = row[11]
        data['trading_route']     = row[12]
        data['daily_visit']       = row[13]
        data['test_version']      = row[14]
#        data['function_flag']     = row[15]
#        data['test_flag']         = row[16]
        data['version_date']      = row[15]
        data['test_status']       = row[16]
        data['function_endtime']          = row[17]
        data['lock_flag']         = row[18]
        data['modified_date']     = row[19]
        data['modifield_user']    = row[20]
        data['subsystem_abbr']    = row[21]
        data['subsystem_name']    = row[22]
        
        sel_his = select([func.distinct(req_his.c.test_id),req_his.c.modified_date],
                    and_(req_his.c.test_id ==  data['test_id'],
                        or_(                                                    
                            req_his.c.system != data['system'],
                            req_his.c.function_name != data['function_name'],
                            req_his.c.function_code != data['function_code'],
                            req_his.c.function_type != data['function_type'],
                            req_his.c.change_status != data['change_status'],
                            req_his.c.using_status != data['using_status'],
                            req_his.c.function_point != data['function_point'],
                            req_his.c.business_degree != data['business_degree'],
                            req_his.c.trading_frequency != data['trading_frequency'],
                            req_his.c.across_system != data['across_system'],
                            req_his.c.trading_origin != data['trading_origin'],
                            req_his.c.trading_route != data['trading_route'],
                            req_his.c.daily_visit != data['daily_visit'],
                            req_his.c.test_version != data['test_version'],
                            req_his.c.subsystem_abbr != data['subsystem_abbr'],
                            req_his.c.subsystem_name != data['subsystem_name']
                            ),
                        req_his.c.modified_date.in_(select([func.max(req_his.c.modified_date)],
                                                            and_(req_his.c.test_id == data['test_id']))),
                        req_his.c.modified_date < data['modified_date'])
                           )
                            

        #print sel_his
        sel_his_rs = sel_his.execute()
        for row in sel_his_rs:
#            print 'firstrow',row,data
            #print 'row_line',row
            r = req_his(**data)
            r.save()
    #------------------------------------
    req = select([req_test.c.id,
                  req_test.c.system,
                  req_test.c.function_name,
                  req_test.c.function_code,
                  req_test.c.function_type,
                  req_test.c.change_status,
                  req_test.c.using_status,
                  req_test.c.function_point,
                  req_test.c.business_degree,
                  req_test.c.trading_frequency,
                  req_test.c.across_system,
                  req_test.c.trading_origin,
                  req_test.c.trading_route,
                  req_test.c.daily_visit,
                  req_test.c.test_version,
#                  req_test.c.function_flag,
#                  req_test.c.test_flag,
                  req_test.c.version_date,
                  req_test.c.test_status,
                  req_test.c.function_endtime,
                  req_test.c.lock_flag,
                  req_test.c.modified_date,
                  req_test.c.modifield_user,
                  req_test.c.subsystem_abbr,
                  req_test.c.subsystem_name],
                and_(req_test.c.version_date >= today,~req_test.c.id.in_(select([req_his.c.test_id]))))
    
    req_rs = req.execute()
    data = {}
    for row in req_rs:
        row = list(row)
        
        #print 'row',row
        
        data['test_id']           = row[0]
        data['system']            = row[1] 
        data['function_name']     = row[2] 
        data['function_code']     = row[3] 
        data['function_type']     = row[4] 
        data['change_status']     = row[5] 
        data['using_status']      = row[6] 
        data['function_point']    = row[7] 
        data['business_degree']   = row[8] 
        data['trading_frequency'] = row[9] 
        data['across_system']     = row[10]
        data['trading_origin']    = row[11]
        data['trading_route']     = row[12]
        data['daily_visit']       = row[13]
        data['test_version']      = row[14]
#        data['function_flag']     = row[15]
#        data['test_flag']         = row[16]
        data['version_date']      = row[15]
        data['test_status']       = row[16]
        data['function_endtime']  = row[17]
        data['lock_flag']         = row[18]
        data['modified_date']     = row[19]
        data['modifield_user']    = row[20]
        data['subsystem_abbr']    = row[21]
        data['subsystem_name']    = row[22]
                                
        #print sel_his

#        print 'his-row',row
        #print 'row_line',row
        r = req_his(**data)
        r.save()
    

#暂时停止测试功能点批处理，20111008        
#if __name__ == '__main__':
#    try:
#        db.begin()
#        run_test_function_backup()
#        db.commit()
#    except:
#        db.rollback()
#        raise
#--------------------每日备份测试功能点结束--------------------#

#--------------------每日任务、里程碑状态更新开始--------------------#
def update_task_milestone_status_run():
    
    #从settings.ini获取任务类型编号
    #settings = Ini('../apps/settings.ini')
    req_task = get_model('tasks_develop')
    req_planexecute = get_model('planexecute')
    req_plan = get_model('plan')
    req_ass = get_model('assignment')
    req_message = get_model('message')
    req_user = get_model('user')
#    req_t_detail = get_model('tasks_develop_report_detail')
    #获取本周末日期
    #删除系统自动批处理的message
    req_message.remove(and_(req_message.c.type=='1'))
    
    
    today = datetime.date.today()
#    tomorrow = today + datetime.timedelta(days=1)
#    today = month_last_day
    sql = select([req_planexecute.c.id,
                  req_planexecute.c.finish_begin_date,
                  req_planexecute.c.finish_end_date,
                  req_planexecute.c.type,
                  req_planexecute.c.status,
                  req_plan.c.begin_date,
                  req_plan.c.end_date],
                  and_(req_plan.c.id == req_planexecute.c.plan))

    rs_sql = sql.execute()
    #根据里程碑或计划的计划时间和完成时间，判断是否延迟
    for row in rs_sql:
        planexecute_id,finish_begin_date,finish_end_date,type,status,begin_date,end_date = row
#        print 'plan_date',plan_date
        if type == '2' and end_date and end_date<=today:
            if not finish_end_date and (not status or status != '2'):
                req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '2')
            elif finish_end_date:
                if end_date < finish_end_date and status != '3':
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '3')
                if end_date == finish_end_date and status != '3':
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '3')
                if end_date > finish_end_date and status != '6':
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        elif type == '2' and end_date and finish_end_date and finish_end_date>end_date and status != '6':
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        elif type == '2' and end_date and not finish_end_date and status != '1' and status != '4' and status != '5':
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '1')
        elif type == '2' and end_date and  finish_end_date and end_date >= finish_end_date and status != '6' and status != '4' and status != '5':
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        
        if type == '1' and begin_date and begin_date <= today and (not end_date or end_date > today) and not finish_end_date:
            if not finish_begin_date and  (not status or status != '2'):
                status = '2'
                req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '2')
            elif finish_begin_date:
                if begin_date < finish_begin_date and status != '2':
                    status = '2'
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '2')
                if begin_date == finish_begin_date and status != '1':
                    status = '1'
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '1')                
#                if begin_date == finish_begin_date and status != '3':
#                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '3')
                if begin_date > finish_begin_date and status != '6':
                    status = '6'
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')                
#        elif type == '1' and begin_date and finish_begin_date and finish_begin_date>begin_date and status != '6' and not finish_end_date:
#            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        elif type == '1' and begin_date  and end_date > today and not finish_begin_date and status != '1' and status != '4' and status != '5' and not finish_end_date:
            status = '1'
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '1')
        elif type == '1' and begin_date  and end_date > today and  finish_begin_date and begin_date > finish_begin_date and status != '6' and status != '4' and status != '5' and not finish_end_date:
            status = '6'
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        
        if type == '1' and end_date and end_date <= today:   
#            print '88888888',finish_end_date,end_date,status,planexecute_id,not finish_end_date and (not status or status != '2')
            if not finish_end_date and (not status or status != '2'):
                req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '2')
            elif finish_end_date:
                if end_date < finish_end_date and status != '3':
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '3')
                if end_date == finish_end_date and status != '3':
#                    print '----',finish_end_date,status
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '3')
#                    print '+++++',finish_end_date,status,planexecute_id
                if end_date > finish_end_date and status != '6':
                    req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')                
#        elif type == '1' and end_date and finish_end_date and finish_end_date>end_date and status != '6':
#            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        elif type == '1' and end_date and  finish_end_date and end_date > finish_end_date and status != '6' and status != '4' and status != '5':
            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '6')
        
#        elif type == '1' and end_date and not finish_end_date and status != '1' and status != '4' and status != '5':
#            req_planexecute.table.update(req_planexecute.c.id == planexecute_id).execute(status = '1')
            
    #---处理任务延迟情况----#
    obj_task =  req_task.filter(or_(and_(req_task.c.stage != 'FN',
                                         req_task.c.stage != '00'),
                                    and_(req_task.c.stage == '00',
                                         req_task.c.begin_time <= today),
#                                    and_(req_task.c.modified_date >= today,
##                                    and_(req_task.c.status != '1',
#                                         req_task.c.stage == 'FN')
                                        )) 
#    obj_task =  req_task.filter(req_task.c.id == 2427)
    for row in obj_task:
        task = row.id
        dev_task = row.task_id    
        delay_stat = ''
        
        #更新任务所属阶段开始
        if not row._version_headerId_:
            condition = and_(req_plan.c.task==task,
                             req_plan.systems.in_(row._task_sys_),
                             req_plan.c.type=='1',
                             req_plan.c.begin_date<=today,
                             req_plan.c.end_date >= today)
        else:
            condition = and_(or_((Plan.c.task==row._version_headerId_) & req_plan.systems.in_(row._task_sys_), 
                             Plan.c.task==row.id),
                             req_plan.c.type=='1',
                             req_plan.c.begin_date<=today,
                             req_plan.c.end_date >= today)
                             
        plan_objs = req_plan.filter(condition).order_by(req_plan.c.end_date.desc()).one()
        if plan_objs and row.stage != 'FN':
            req_task.table.update(req_task.c.id ==task).execute(stage = plan_objs.stage)
#        if task == 38:
#            print 'mmmmmmmmmmmm',task,plan_objs.stage
        #更新任务所属阶段结束
     
        weight_total = 0
        weight_delay = 0
        milestone_change = 0
        change_milestone = ''

        #获取任务里程碑或计划延迟情况
#        delay_stat,weight_delay,weight_total = get_task_plan_delay(row,today,today)
#        if task == 2427:
#            print delay_stat.encode('gbk'),weight_delay,weight_total
        delay_stat = req_planexecute.get(and_(req_planexecute.c.task==row.id,req_planexecute.c.status=='2'))
        if (delay_stat or (row.end_time < today and row.status != '3' and row.stage != 'FN')) and row.status != '4' and row.status != '5' :
            req_task.table.update(req_task.c.id ==task).execute(status = '2')
#            if row.id==3640:
#                print '+++=',delay_stat#,weight_delay,weight_total
#            if row.status != '2':
#                req_ass.table.update(req_ass.c.id ==row.assignment.id).execute(status = '2')
        elif row.status == '2':
            req_task.table.update(req_task.c.id ==task).execute(status = '1')
        
        message_plan_delay = select([req_plan.c.title],and_(req_planexecute.c.task == task,
                                                           req_planexecute.c.status == '2',
                                                           req_plan.c.id == req_planexecute.c.plan))
        sql_mess_delay = message_plan_delay.execute()
        plan_delay_stat = u''
        for row_mess in sql_mess_delay:
            plan_name, = row_mess
            plan_delay_stat = plan_delay_stat + plan_name
        if plan_delay_stat != '':
            #将任务延迟情况写入message表
            users = set(row.task_sys.users.ids())
            users = list(users)
            #         users = row.get_receiver_ids(None)
            message_data=[]
            for row1 in users:
                #判断如果该用户无对应用户，则跳过
                a = req_user.get(req_user.c.id == row1)
                if not a:
            #                 print row1
                    continue
            #             if row1 == 225:
            #                 print 'xxxx',users
                task_message = get_init_message_data()
            #             task_message['memo'] = str(Tag('a', row.task_id +'-'+ u'任务里程碑延迟:'+delay_stat, href=str('/tasks/develop/'+str(row.id)),target='_blank'))
                task_message['memo'] = str(Tag('a', "<font color='red'>"+row.task_id + u'-'+row.name + u'-'+ u'任务里程碑延迟:'+plan_delay_stat+"</font>", href=str('/tasks/develop/'+str(row.id)),target='_blank'))
            #          task_message['memo'] = "<font color='red'>"+str(Tag('a', u'任务延迟', href=str('/tasks/develop/list'+'?'+'task_id'+'='+row.task_id),target='_blank'))+"</font>"
                task_message['type'] = '1'
                task_message['user'] = row1
                task_message['read_flag'] = False
                task_message['sender'] = None
                task_message['create_date'] = datetime.datetime.now() + datetime.timedelta(days=1)
                message_data.append(task_message)
            save_new_message(message_data)
        
        #------------获取一天后将可能延迟的任务开始------------------------#
        oneday = datetime.timedelta(days=1)
        nextdaybegin = today + oneday
        nextdayend = today + oneday
        reminder_plan = select([req_plan.c.title,
                        req_plan.c.type,
                        req_plan.c.begin_date,
                        req_plan.c.end_date,
                        req_planexecute.c.finish_begin_date,
                        req_planexecute.c.finish_end_date,
                        req_plan.c.weight],
                        and_(req_planexecute.c.task == task,
                                req_plan.c.id == req_planexecute.c.plan,
                                req_planexecute.c.status == '1',
                                or_(and_(req_plan.c.type == '1',
                                        or_(and_(req_plan.c.begin_date >= nextdaybegin,
                                                 req_plan.c.begin_date <= nextdayend),
                                            and_(req_plan.c.end_date >= nextdaybegin,
                                                 req_plan.c.end_date <= nextdayend))
                                            ),
                                    and_(req_plan.c.type == '2',
                                        req_plan.c.end_date >= nextdaybegin,
                                        req_plan.c.end_date <= nextdayend,
                                        req_planexecute.c.finish_end_date == None
                                         )
                                    )
                            ))
        
        
        rs_reminder_plan = reminder_plan.execute()
        reminder_stat = ''
        for row5 in rs_reminder_plan:
            reminder_stat = reminder_stat + row5[0] + u';'
            
#        delay_stat,weight_delay,weight_total = get_task_plan_delay(row,nextday,nextday)
        
        if reminder_stat and (row.status != '4' or row.status != '5' ):            
            #将任务延迟情况写入message表
#            users = row.get_receiver_ids(None)
            users = set(row.task_sys.users.ids())
            users = list(users)
            
            message_data=[]
            for row1 in users:
                #判断如果该用户无对应用户，则跳过
                a = req_user.get(req_user.c.id == row1)
                if not a:
#                    print row1
                    continue                
                task_message = get_init_message_data()
                task_message['memo'] = str(Tag('a', "<font color='#ff8800'>"+row.task_id + u'-' + row.name +u'-'+ u'任务有里程碑将于明天到期:'+reminder_stat+"</font>", href=str('/tasks/develop/'+str(row.id)),target='_blank'))
        #           task_message['memo'] = "<font color='red'>"+str(Tag('a', u'任务延迟', href=str('/tasks/develop/list'+'?'+'task_id'+'='+row.task_id),target='_blank'))+"</font>"
                task_message['type'] = '1'
                task_message['user'] = row1
                task_message['read_flag'] = False
                task_message['sender'] = None
                task_message['create_date'] = datetime.datetime.now() + datetime.timedelta(days=1)
                message_data.append(task_message)
            save_new_message(message_data)
        #------------获取一天后将可能延迟的任务开始------------------------#
        
if __name__ == '__main__':
    try:
        db.begin()
        update_task_milestone_status_run()
        db.commit()
        log.info("finish")
    except Exception, e:
        db.rollback()
        log.exception(e)
        log.error('error')
        raise


#--------------------任务书延迟状态更新开始--------------------#
def run_delay_flag():

    first_day = datetime.date.today()
    last_day = first_day

    req_ass = get_model('assignment')
    req_task = get_model('tasks_develop')
    req_user = get_model('user')
    
    today = datetime.date.today()
    
    
    sql_ass = req_ass.filter(and_(req_ass.c.stage != 'FN'))
    for row in sql_ass:
        sql_task = req_task.filter(and_(req_task.c.assignment == row.id,
                                        req_task.c.stage != 'FN',
                                        req_task.c.status == '2'))
        delay_flag = 0
        for row1 in sql_task:
            if row1:
                delay_flag = 1
                if row.status != '2' and row.status != '3' and row.status != '4' and row.status != '5':
                    req_ass.table.update(req_ass.c.id ==row.id).execute(status = '2')
            break
        if delay_flag == 0 and row.status == '2':
            req_ass.table.update(req_ass.c.id ==row.id).execute(status = '1')
        if row.end_date < last_day and row.status != '2' and row.stage != 'FN' and row.stage != '16' and row.status != '4' and row.status != '5':
            req_ass.table.update(req_ass.c.id ==row.id).execute(status = '2')
            
        #任务书结果延迟情况写入message表
        if row.end_date < last_day and row.stage != 'FN' and row.stage != '16' and row.status != '4' and row.status != '5':
            users = row.get_receiver_ids(None)
            
            message_data=[]
            for row1 in users:
                #判断如果该用户无对应用户，则跳过
                a = req_user.get(req_user.c.id == row1)
                if not a:
#                    print row1
                    continue
                task_message = get_init_message_data()
                task_message['memo'] = str(Tag('a', "<font color='red'>"+row.ass_id +u'-'+ u'任务书已过结束时间'+"</font>", href=str('/assignments/'+str(row.id)),target='_blank'))
                task_message['type'] = '1'
                task_message['user'] = row1
                task_message['read_flag'] = False
                task_message['sender'] = None
                task_message['create_date'] = datetime.datetime.now() + datetime.timedelta(days=1)
                message_data.append(task_message)
            save_new_message(message_data)
            

if __name__ == '__main__':
    try:
        db.begin()
        run_delay_flag()
        db.commit()
        log.info("finish")
    except Exception, e:
        db.rollback()
        log.exception(e)
        log.error('error')
        raise

#--------------------任务书延迟状态更新结束--------------------#
#--------------------每日任务、里程碑状态更新结束--------------------#


